' Fluid dynamics test
' Original C code written by Jos Stam (<a href="mailto:jstam@aw.sgi.com">jstam@aw.sgi.com</a>)

SuperStrict

Framework BRL.blitz
Import BRL.glmax2d
Import BRL.max2d
Import BRL.retro


Import "solver.c"

Extern
	Function dens_step(N:Int, x:Float Ptr, x0:Float Ptr, u:Float Ptr, v:Float Ptr, diff:Float, dt:Float)
	Function vel_step(N:Int, u:Float Ptr, v:Float Ptr, u0:Float Ptr, v0:Float Ptr, visc:Float, dt:Float)
End Extern

SetGraphicsDriver GLMax2DDriver()
Graphics 800,600,32,0

Const gridSize:Int = 96
Const diffusion:Float = 0.0
Const deltaTime:Float = 0.1
Const viscosity:Float = .0001
Const force:Float = .2
Const source:Float = 4.0

Global bytesize:Int = (gridSize+2)*(gridSize+2)
Global densities:Float[byteSize]
Global densitiesPtr:Float Ptr = densities
Global xVelocities:Float[byteSize]
Global xVelocitiesPtr:Float Ptr = xVelocities
Global yVelocities:Float[byteSize]
Global yVelocitiesPtr:Float Ptr = yVelocities

Global densitiesPrevious:Float[byteSize]
Global densitiesPreviousPtr:Float Ptr = densitiesPrevious
Global xVelocitiesPrevious:Float[byteSize]
Global xVelocitiesPreviousPtr:Float Ptr = xVelocitiesPrevious
Global yVelocitiesPrevious:Float[byteSize]
Global yVelocitiesPreviousPtr:Float Ptr = yVelocitiesPrevious

Global omx:Int = GraphicsWidth()/2
Global omy:Int = GraphicsHeight()/2

' mainloop
While Not KeyHit(KEY_ESCAPE)

	For Local i:Int = 0 To (byteSize)-1
		densitiesPrevious[i] = 0.0
		xVelocitiesPrevious[i] = 0.0
		yVelocitiesPrevious[i] = 0.0
	Next
	
	userInput()
	vel_step(gridSize, xVelocitiesPtr, yVelocitiesPtr, xVelocitiesPreviousPtr, yVelocitiesPreviousPtr, viscosity, deltaTime)
	dens_step(gridSize, densitiesPtr, densitiesPreviousPtr, xVelocitiesPtr, yVelocitiesPtr, diffusion, deltaTime )
	renderDensity()
			
	Flip

Wend

End

Function userInput()

	Local x:Int = 0+((MouseX()/Float(GraphicsWidth()))*(gridSize-4)) 
	Local y:Int = 0+((MouseY()/Float(GraphicsHeight()))*(gridSize-4))
	Local offset:Int = x+(gridSize+2)*y

	If offset < byteSize
		If MouseDown(1)
			densities[offset] = source
		Else If KeyDown(KEY_SPACE)
			densities[offset] = -source
		End If
		xVelocities[offset] = force * (MouseX()-omx)
		yVelocities[offset] = force * (MouseY()-omy)
	End If
		
	omx = MouseX()
	omy = MouseY()
	
End Function

Function renderDensity()

	Local w:Float = GraphicsWidth()/gridSize+1
	Local h:Float = GraphicsHeight()/gridSize+1
	
	glBegin(GL_QUADS)

	For Local y:Int = 0 To gridSize-1
		Local yy:Float = (y-0.5)*h
		Local yoffset:Int = (gridSize+2)*y
		For Local x:Int = 0 To gridSize-1
			Local xx:Float = (x-0.5)*w 
	
			Local d00:Float = densities[yoffset+x]
			Local d01:Float = densities[yoffset+x+gridSize+2]
			Local d10:Float = densities[yoffset+x+1]
			Local d11:Float = densities[yoffset+x+1+gridSize+2]

			glColor3f(d00,d00,d00*2.0) ; glVertex2f(xx,yy)
			glColor3f(d10,d10,d10*2.0) ; glVertex2f(xx+w,yy)
			glColor3f(d11,d11,d11*2.0) ; glVertex2f(xx+w,yy+h)
			glColor3f(d01,d01,d01*2.0) ; glVertex2f(xx,yy+h)
			
		Next	
	Next

	glEnd()	

End Function


